home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 42
/
Amiga Format AFCD42 (Issue 126, Aug 1999).iso
/
-serious-
/
programming
/
other
/
jikes
/
src
/
lookup.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-14
|
42KB
|
1,520 lines
// $Id: lookup.cpp,v 1.5 1999/02/12 14:39:13 shields Exp $
//
// This software is subject to the terms of the IBM Jikes Compiler
// License Agreement available at the following URL:
// http://www.ibm.com/research/jikes.
// Copyright (C) 1996, 1998, International Business Machines Corporation
// and others. All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
#include "config.h"
#include <iostream.h>
#include "lookup.h"
#include "symbol.h"
#include "code.h"
#include "ast.h"
#include "case.h"
int IntLiteralTable::int32_limit = 0x7FFFFFFF / 10;
LongInt LongLiteralTable::int64_limit = LongInt(0x7FFFFFFF, 0xFFFFFFFF) / 10;
int DirectoryTable::primes[] = {DEFAULT_HASH_SIZE, 2039, 4093, MAX_HASH_SIZE};
DirectoryTable::DirectoryTable(int estimate) : entry_pool(estimate),
prime_index(0),
hash_size(primes[0])
{
base = (DirectoryEntry **) memset(new DirectoryEntry *[hash_size], 0, hash_size * sizeof(DirectoryEntry *));
}
DirectoryTable::~DirectoryTable()
{
/*
int n;
int num_slots = 0;
int total = 0;
for (n = 0; n < hash_size; n++)
{
int num = 0;
for (Symbol *s = base[n]; s; s = s -> next)
num++;
if (num > 0)
{
num_slots++;
total += num;
}
}
if (num_slots > 0)
{
cout << "\nDestroying the Name table with " << total
<< " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
for (n = 0; n < hash_size; n++)
{
int num = 0;
for (Symbol *s = base[n]; s; s = s -> next)
num++;
if (num > 0)
cout << " slot " << n << " contains " << num << " element(s)\n";
}
}
if (hash_size < total)
total = total;
*/
#ifdef TEST
for (int i = 0; i < entry_pool.Length(); i++)
delete entry_pool[i];
delete [] base;
#endif
}
time_t DirectoryEntry::Mtime()
{
if (mtime_ == 0)
{
char *dirname = this -> directory -> DirectoryName();
int length = this -> directory -> DirectoryNameLength() + this -> length + 1; // +1 for '/'
char *file_name = new char[length + 1];
strcpy(file_name, dirname);
if (dirname[this -> directory -> DirectoryNameLength() - 1] != U_SLASH)
strcat(file_name, StringConstant::U8S__SL_);
strcat(file_name, this -> name);
struct stat status;
if (::SystemStat(file_name, &status) == 0)
mtime_ = status.st_mtime;
else
assert("Cannot compute system time stamp\n");
delete [] file_name;
}
return mtime_;
}
DirectoryEntry *DirectoryTable::FindEntry(char *str, int len)
{
int k = Hash(str, len) % hash_size;
DirectoryEntry *entry;
for (entry = base[k]; entry; entry = entry -> next)
{
if (len == entry -> length && memcmp(entry -> name, str, len * sizeof(char)) == 0)
return (entry -> IsDummy() ? (DirectoryEntry *) NULL : entry);
}
return NULL;
}
void DirectoryTable::Rehash()
{
hash_size = primes[++prime_index];
delete [] base;
base = (DirectoryEntry **) memset(new DirectoryEntry *[hash_size], 0, hash_size * sizeof(DirectoryEntry *));
for (int i = 0; i < entry_pool.Length(); i++)
{
DirectoryEntry *e = entry_pool[i];
int k = Hash(e -> name, e -> length) % hash_size;
e -> next = base[k];
base[k] = e;
}
return;
}
DirectoryEntry *DirectoryTable::InsertEntry(DirectorySymbol *directory_symbol, char *str, int len)
{
int k = Hash(str, len) % hash_size;
DirectoryEntry *entry;
for (entry = base[k]; entry; entry = entry -> next)
{
if (len == entry -> length && memcmp(entry -> name, str, len * sizeof(char)) == 0)
return entry;
}
entry = new DirectoryEntry();
entry_pool.Next() = entry;
entry -> Initialize(directory_symbol, str, len);
entry -> next = base[k];
base[k] = entry;
//
// If the number of unique elements in the hash table exceeds 2 times
// the size of the base, and we have not yet reached the maximum
// allowable size for a base, reallocate a larger base and rehash
// the elements.
//
if ((hash_size < MAX_HASH_SIZE) && (entry_pool.Length() > (hash_size << 1)))
Rehash();
return entry;
}
#ifdef WIN32_FILE_SYSTEM
DirectoryEntry *DirectoryTable::FindCaseInsensitiveEntry(char *name, int length)
{
char *lower_name = new char[length + 1];
for (int i = 0; i < length; i++)
lower_name[i] = Case::ToAsciiLower(name[i]);
lower_name[length] = U_NULL;
DirectoryEntry *entry = FindEntry(lower_name, length);
delete [] lower_name;
return (entry ? entry -> Image() : entry);
}
void DirectoryTable::InsertCaseInsensitiveEntry(DirectoryEntry *image)
{
int length = image -> length;
char *lower_name = new char[length + 1];
for (int i = 0; i < length; i++)
lower_name[i] = Case::ToAsciiLower(image -> name[i]);
lower_name[length] = U_NULL;
int k = Hash(lower_name, length) % hash_size;
DirectoryEntry *entry;
for (entry = base[k]; entry; entry = entry -> next)
{
if (length == entry -> length && memcmp(entry -> name, lower_name, length * sizeof(char)) == 0)
break;
}
if (! entry)
{
FoldedDirectoryEntry *folded_entry = new FoldedDirectoryEntry(image);
entry_pool.Next() = folded_entry;
folded_entry -> Initialize(image, lower_name, length);
folded_entry -> next = base[k];
base[k] = folded_entry;
//
// If the number of unique elements in the hash table exceeds 2 times
// the size of the base, and we have not yet reached the maximum
// allowable size for a base, reallocate a larger base and rehash
// the elements.
//
if ((hash_size < MAX_HASH_SIZE) && (entry_pool.Length() > (hash_size << 1)))
Rehash();
}
delete [] lower_name;
return;
}
#endif
int NameLookupTable::primes[] = {DEFAULT_HASH_SIZE, 8191, 16411, MAX_HASH_SIZE};
NameLookupTable::NameLookupTable(int estimate) : symbol_pool(estimate),
prime_index(0),
hash_size(primes[0])
{
base = (NameSymbol **) memset(new NameSymbol *[hash_size], 0, hash_size * sizeof(NameSymbol *));
}
NameLookupTable::~NameLookupTable()
{
/*
int n;
int num_slots = 0;
int total = 0;
for (n = 0; n < hash_size; n++)
{
int num = 0;
for (Symbol *s = base[n]; s; s = s -> next)
num++;
if (num > 0)
{
num_slots++;
total += num;
}
}
if (num_slots > 0)
{
cout << "\nDestroying the Name table with " << total
<< " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
for (n = 0; n < hash_size; n++)
{
int num = 0;
for (Symbol *s = base[n]; s; s = s -> next)
num++;
if (num > 0)
cout << " slot " << n << " contains " << num << " element(s)\n";
}
}
if (hash_size < total)
total = total;
*/
#ifdef TEST
for (int i = 0; i < symbol_pool.Length(); i++)
delete symbol_pool[i];
delete [] base;
#endif
}
int LiteralLookupTable::primes[] = {DEFAULT_HASH_SIZE, 2039, 4093, MAX_HASH_SIZE};
LiteralLookupTable::LiteralLookupTable() : symbol_pool(16384),
prime_index(0),
hash_size(primes[0])
{
base = (LiteralSymbol **) memset(new LiteralSymbol *[hash_size], 0, hash_size * sizeof(LiteralSymbol *));
}
LiteralLookupTable::~LiteralLookupTable()
{
/*
int n;
int num_slots = 0;
int total = 0;
for (n = 0; n < hash_size; n++)
{
int num = 0;
for (Symbol *s = base[n]; s; s = s -> next)
num++;
if (num > 0)
{
num_slots++;
total += num;
}
}
if (num_slots > 0)
{
cout << "\nDestroying the Literal table with " << total
<< " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
for (n = 0; n < hash_size; n++)
{
int num = 0;
for (Symbol *s = base[n]; s; s = s -> next)
num++;
if (num > 0)
cout << " slot " << n << " contains " << num << " element(s)\n";
}
}
if (hash_size < total)
total = total;
*/
#ifdef TEST
for (int i = 0; i < symbol_pool.Length